"""
AI服务管理器
AI Services Manager

统一管理所有AI算法服务：
- 服务注册和发现
- 任务调度和分发
- 结果收集和处理
- 性能监控和统计
"""
import logging
import asyncio
from typing import Dict, List, Optional, Any, Callable
from datetime import datetime
from dataclasses import dataclass
from enum import Enum
import time

from core.camera_service import get_camera_service
from core.video_service import get_video_service
from core.frame_processor import get_frame_processor
from database.simple_db import get_database_manager

logger = logging.getLogger(__name__)


class AIServiceType(str, Enum):
    """AI服务类型枚举"""
    BEHAVIOR_MONITORING = "behavior_monitoring"
    CROWD_SAFETY = "crowd_safety"
    ENERGY_MANAGEMENT = "energy_management"
    ENVIRONMENT_HYGIENE = "environment_hygiene"
    CLASSROOM_QUALITY = "classroom_quality"
    TEACHING_ASSESSMENT = "teaching_assessment"


@dataclass
class AIServiceInfo:
    """AI服务信息"""
    service_type: AIServiceType
    service_name: str
    description: str
    is_enabled: bool
    is_running: bool
    last_update: Optional[datetime]
    processing_count: int
    error_count: int
    average_processing_time: float


@dataclass
class AITaskResult:
    """AI任务结果"""
    camera_id: str
    service_type: AIServiceType
    timestamp: datetime
    processing_time: float
    success: bool
    result_data: Dict[str, Any]
    error_message: Optional[str] = None


class AIServiceManager:
    """AI服务管理器"""
    
    def __init__(self):
        self.services: Dict[AIServiceType, Any] = {}
        self.service_info: Dict[AIServiceType, AIServiceInfo] = {}
        self.is_running = False
        
        # 依赖服务
        self.camera_service = get_camera_service()
        self.video_service = get_video_service()
        self.frame_processor = get_frame_processor()
        self.db = get_database_manager()
        
        # 统计信息
        self.stats = {
            "total_tasks": 0,
            "successful_tasks": 0,
            "failed_tasks": 0,
            "average_processing_time": 0.0,
            "services_count": 0,
            "active_services": 0
        }
    
    def register_service(self, service_type: AIServiceType, service_instance: Any, 
                        service_name: str, description: str):
        """注册AI服务"""
        try:
            self.services[service_type] = service_instance
            self.service_info[service_type] = AIServiceInfo(
                service_type=service_type,
                service_name=service_name,
                description=description,
                is_enabled=True,
                is_running=False,
                last_update=None,
                processing_count=0,
                error_count=0,
                average_processing_time=0.0
            )
            
            self.stats["services_count"] = len(self.services)
            logger.info(f"AI服务注册成功: {service_name} ({service_type})")
            
        except Exception as e:
            logger.error(f"AI服务注册失败: {service_name} - {e}")
    
    def unregister_service(self, service_type: AIServiceType):
        """注销AI服务"""
        try:
            if service_type in self.services:
                service_name = self.service_info[service_type].service_name
                del self.services[service_type]
                del self.service_info[service_type]
                
                self.stats["services_count"] = len(self.services)
                logger.info(f"AI服务注销成功: {service_name} ({service_type})")
            
        except Exception as e:
            logger.error(f"AI服务注销失败: {service_type} - {e}")
    
    def enable_service(self, service_type: AIServiceType):
        """启用AI服务"""
        if service_type in self.service_info:
            self.service_info[service_type].is_enabled = True
            logger.info(f"AI服务已启用: {service_type}")
    
    def disable_service(self, service_type: AIServiceType):
        """禁用AI服务"""
        if service_type in self.service_info:
            self.service_info[service_type].is_enabled = False
            self.service_info[service_type].is_running = False
            logger.info(f"AI服务已禁用: {service_type}")
    
    async def process_frame(self, camera_id: str, frame, 
                           service_types: List[AIServiceType] = None) -> List[AITaskResult]:
        """处理视频帧"""
        if service_types is None:
            service_types = list(self.services.keys())
        
        results = []
        
        for service_type in service_types:
            if service_type not in self.services:
                continue
            
            service_info = self.service_info[service_type]
            if not service_info.is_enabled:
                continue
            
            try:
                start_time = time.time()
                service = self.services[service_type]
                
                # 标记服务为运行状态
                service_info.is_running = True
                
                # 执行AI处理
                if hasattr(service, 'analyze_frame'):
                    result_data = await service.analyze_frame(frame, camera_id)
                else:
                    logger.warning(f"服务 {service_type} 没有 analyze_frame 方法")
                    continue
                
                processing_time = time.time() - start_time
                
                # 创建任务结果
                task_result = AITaskResult(
                    camera_id=camera_id,
                    service_type=service_type,
                    timestamp=datetime.now(),
                    processing_time=processing_time,
                    success=True,
                    result_data=result_data if isinstance(result_data, dict) else {"results": result_data}
                )
                
                results.append(task_result)
                
                # 更新服务统计
                self._update_service_stats(service_type, processing_time, True)
                
                # 保存结果到数据库
                await self._save_ai_result(task_result)
                
            except Exception as e:
                processing_time = time.time() - start_time if 'start_time' in locals() else 0
                
                # 创建错误结果
                task_result = AITaskResult(
                    camera_id=camera_id,
                    service_type=service_type,
                    timestamp=datetime.now(),
                    processing_time=processing_time,
                    success=False,
                    result_data={},
                    error_message=str(e)
                )
                
                results.append(task_result)
                
                # 更新服务统计
                self._update_service_stats(service_type, processing_time, False)
                
                logger.error(f"AI服务处理失败: {service_type} - {e}")
            
            finally:
                # 标记服务为非运行状态
                if service_type in self.service_info:
                    self.service_info[service_type].is_running = False
        
        # 更新全局统计
        self._update_global_stats(results)
        
        return results
    
    def _update_service_stats(self, service_type: AIServiceType, processing_time: float, success: bool):
        """更新服务统计信息"""
        if service_type not in self.service_info:
            return
        
        service_info = self.service_info[service_type]
        service_info.last_update = datetime.now()
        service_info.processing_count += 1
        
        if success:
            # 更新平均处理时间
            current_avg = service_info.average_processing_time
            count = service_info.processing_count
            service_info.average_processing_time = (current_avg * (count - 1) + processing_time) / count
        else:
            service_info.error_count += 1
    
    def _update_global_stats(self, results: List[AITaskResult]):
        """更新全局统计信息"""
        self.stats["total_tasks"] += len(results)
        
        successful_results = [r for r in results if r.success]
        self.stats["successful_tasks"] += len(successful_results)
        self.stats["failed_tasks"] += len(results) - len(successful_results)
        
        # 更新平均处理时间
        if successful_results:
            total_time = sum(r.processing_time for r in successful_results)
            avg_time = total_time / len(successful_results)
            
            total_successful = self.stats["successful_tasks"]
            current_avg = self.stats["average_processing_time"]
            
            if total_successful > len(successful_results):
                # 计算新的平均值
                prev_total = total_successful - len(successful_results)
                self.stats["average_processing_time"] = (current_avg * prev_total + total_time) / total_successful
            else:
                self.stats["average_processing_time"] = avg_time
        
        # 更新活跃服务数
        self.stats["active_services"] = sum(1 for info in self.service_info.values() if info.is_running)
    
    async def _save_ai_result(self, task_result: AITaskResult):
        """保存AI结果到数据库"""
        try:
            if task_result.success and task_result.result_data:
                self.db.save_ai_result(
                    camera_id=int(task_result.camera_id) if task_result.camera_id.isdigit() else 0,
                    algorithm=task_result.service_type.value,
                    result_data=task_result.result_data,
                    confidence=task_result.result_data.get('confidence', 0.0),
                    processing_time=task_result.processing_time
                )
        except Exception as e:
            logger.error(f"保存AI结果失败: {e}")
    
    async def process_camera_stream(self, camera_id: str, service_types: List[AIServiceType] = None):
        """处理摄像头视频流"""
        try:
            # 启动视频流处理
            success = await self.video_service.start_stream_processing(camera_id)
            if not success:
                logger.error(f"启动视频流失败: {camera_id}")
                return
            
            logger.info(f"开始处理摄像头流: {camera_id}")
            
            # 持续处理帧
            while self.is_running:
                try:
                    # 提取帧
                    frame_data = await self.video_service.extract_frame(camera_id)
                    if frame_data is None:
                        await asyncio.sleep(0.1)
                        continue
                    
                    # 处理帧
                    results = await self.process_frame(camera_id, frame_data.frame, service_types)
                    
                    # 处理结果（如发送告警等）
                    await self._handle_results(results)
                    
                except Exception as e:
                    logger.error(f"处理摄像头流异常: {camera_id} - {e}")
                    await asyncio.sleep(1)
            
        except Exception as e:
            logger.error(f"摄像头流处理失败: {camera_id} - {e}")
        
        finally:
            # 停止视频流处理
            await self.video_service.stop_stream_processing(camera_id)
            logger.info(f"摄像头流处理结束: {camera_id}")
    
    async def _handle_results(self, results: List[AITaskResult]):
        """处理AI分析结果"""
        for result in results:
            if not result.success:
                continue
            
            # 检查是否有告警
            if isinstance(result.result_data, dict):
                if 'alert_level' in result.result_data:
                    alert_level = result.result_data.get('alert_level')
                    if alert_level in ['warning', 'danger', 'emergency']:
                        logger.warning(f"AI告警: {result.service_type} - {result.camera_id} - {alert_level}")
                        # 这里可以添加告警处理逻辑
    
    def get_service_info(self, service_type: AIServiceType = None) -> Dict[str, Any]:
        """获取服务信息"""
        if service_type:
            return self.service_info.get(service_type).__dict__ if service_type in self.service_info else {}
        else:
            return {
                service_type.value: info.__dict__ 
                for service_type, info in self.service_info.items()
            }
    
    def get_statistics(self) -> Dict[str, Any]:
        """获取统计信息"""
        return {
            **self.stats,
            "timestamp": datetime.now().isoformat(),
            "is_running": self.is_running,
            "services": {
                service_type.value: {
                    "enabled": info.is_enabled,
                    "running": info.is_running,
                    "processing_count": info.processing_count,
                    "error_count": info.error_count,
                    "average_processing_time": info.average_processing_time
                }
                for service_type, info in self.service_info.items()
            }
        }
    
    async def start(self):
        """启动AI服务管理器"""
        self.is_running = True
        logger.info("AI服务管理器启动")
    
    async def stop(self):
        """停止AI服务管理器"""
        self.is_running = False
        logger.info("AI服务管理器停止")
    
    async def cleanup(self):
        """清理资源"""
        await self.stop()
        
        # 清理所有服务
        for service_type, service in self.services.items():
            try:
                if hasattr(service, 'cleanup'):
                    await service.cleanup()
            except Exception as e:
                logger.error(f"清理AI服务失败: {service_type} - {e}")
        
        logger.info("AI服务管理器资源清理完成")


# 全局AI服务管理器实例
_ai_manager: Optional[AIServiceManager] = None


def get_ai_manager() -> AIServiceManager:
    """获取AI服务管理器实例"""
    global _ai_manager
    if _ai_manager is None:
        _ai_manager = AIServiceManager()
    return _ai_manager